home *** CD-ROM | disk | FTP | other *** search
/ Inter.Net 55-1 / Inter.Net 55-1.iso / CBuilder / Setup / BCB / data.z / bitset.cc < prev    next >
Encoding:
C/C++ Source or Header  |  1998-02-09  |  6.6 KB  |  241 lines

  1. #ifndef __BITSET_CC
  2. #define __BITSET_CC
  3. #pragma option push -b -a4 -Vx- -Ve- -w-inl -w-aus -w-sig
  4.  
  5. /***************************************************************************
  6.  *
  7.  * bitset - class bitset declaration
  8.  *
  9.  * $Id: bitset.cc,v 1.2 1996/08/28 01:28:21 smithey Exp $
  10.  *
  11.  ***************************************************************************
  12.  *
  13.  * (c) Copyright 1994, 1995 Rogue Wave Software, Inc.
  14.  * ALL RIGHTS RESERVED *
  15.  * The software and information contained herein are proprietary to, and
  16.  * comprise valuable trade secrets of, Rogue Wave Software, Inc., which
  17.  * intends to preserve as trade secrets such software and information.
  18.  * This software is furnished pursuant to a written license agreement and
  19.  * may be used, copied, transmitted, and stored only in accordance with
  20.  * the terms of such license and with the inclusion of the above copyright
  21.  * notice.  This software and information or any other copies thereof may
  22.  * not be provided or otherwise made available to any other person.
  23.  *
  24.  * Notwithstanding any other lease or license that may pertain to, or
  25.  * accompany the delivery of, this computer software and information, the
  26.  * rights of the Government regarding its use, reproduction and disclosure
  27.  * are as set forth in Section 52.227-19 of the FARS Computer
  28.  * Software-Restricted Rights clause.
  29.  * 
  30.  * Use, duplication, or disclosure by the Government is subject to
  31.  * restrictions as set forth in subparagraph (c)(1)(ii) of the Rights in
  32.  * Technical Data and Computer Software clause at DFARS 252.227-7013.
  33.  * Contractor/Manufacturer is Rogue Wave Software, Inc.,
  34.  * P.O. Box 2328, Corvallis, Oregon 97339.
  35.  *
  36.  * This computer software and information is distributed with "restricted
  37.  * rights."  Use, duplication or disclosure is subject to restrictions as
  38.  * set forth in NASA FAR SUP 18-52.227-79 (April 1985) "Commercial
  39.  * Computer Software-Restricted Rights (April 1985)."  If the Clause at
  40.  * 18-52.227-74 "Rights in Data General" is specified in the contract,
  41.  * then the "Alternate III" clause applies.
  42.  *
  43.  **************************************************************************/
  44.  
  45. #include <stdcomp.h>
  46.  
  47. #ifndef _RWSTD_NO_NAMESPACE
  48. namespace std {
  49. #endif
  50.  
  51. #ifndef NELEMENTS
  52. #  ifndef _RWSTD_BC5_ENUM_BUG
  53. #define NELEMENTS NumOfElems
  54. #  else
  55. #define NELEMENTS NumOfElems()
  56. #  endif /*_RWSTD_BC5_ENUM_BUG*/
  57. #endif /* NELEMENTS */
  58.  
  59. #ifndef _RWSTD_MSC22_STATIC_INIT_BUG
  60. template <size_t N>
  61. const size_t bitset<N>::bitset_size 
  62. #ifdef _RWSTD_NO_STI_TEMPLATE
  63. = N
  64. #endif
  65. ;
  66. #endif /* _RWSTD_MSC22_STATIC_INIT_BUG */
  67.  
  68. template <size_t N>
  69. bitset<N>::bitset (const string& str,
  70.                    size_t pos,
  71.                    size_t n) _RWSTD_THROW_SPEC((out_of_range, invalid_argument))
  72. #ifdef _RWSTD_MSC22_STATIC_INIT_BUG
  73.   : bitset_size(N)
  74. #endif
  75. {
  76.     size_t slen = str.size();
  77.  
  78.     _RWSTD_THROW(pos > slen,
  79.                 out_of_range,
  80.                 __rw_bitset_InvalidPosition);
  81.  
  82.     size_t rlen = n < (slen - pos) ? n : slen - pos;
  83.     size_t M = N >= rlen ? rlen : N;
  84. #ifndef _RWSTD_BC5_ENUM_BUG
  85.     memset(bits, 0, sizeof(bits));
  86. #else
  87.     bits = new VectorType[NELEMENTS];
  88.     //
  89.     // TODO -- check for bits == 0 here?
  90.     //
  91.     memset(bits, 0, NELEMENTS*sizeof(VectorType));
  92. #endif /*_RWSTD_BC5_ENUM_BUG*/
  93.     for (size_t i = pos; i < M + pos; i++)
  94.     {
  95.         char c = str[slen - i - 1];
  96.  
  97.         _RWSTD_THROW(!(c == '0' || c == '1'),
  98.                     invalid_argument,
  99.                     __rw_bitset_InvalidCtorArgument);
  100.  
  101.         if (c == '1') set(i - pos);
  102.     }
  103. }
  104.  
  105. //
  106. // Constructs an object of type string and initializes it
  107. // to a string of length N characters. Each character is
  108. // determined by the value of its corresponding bit position
  109. // in *this. Character position N-1 corresponds to bit
  110. // position zero. Subsequent decreasing character positions
  111. // correspond to increasing bit positions. Bit value zero becomes
  112. // the character 0, bit value one becomes the character 1.
  113. //
  114.  
  115. template <size_t N>
  116. string 
  117. bitset<N>::to_string () const 
  118. {
  119.     string s;
  120.     for (long i = N - 1; i >= 0; --i)
  121.         s.append(1, test(i) ? '1' : '0');
  122.     return s;
  123. }
  124.  
  125. //
  126. // If the integral value x corresponding to the bitset in *this
  127. // cannot be represented as type unsigned long, throws overflow_error.
  128. //
  129.  
  130. template <size_t N>
  131. unsigned long
  132. bitset<N>::to_ulong () const _RWSTD_THROW_SPEC((overflow_error))
  133. {
  134.     const size_t size_long = sizeof(unsigned long);
  135.  
  136.     for (size_t i = NELEMENTS-1; size_long/sizeof(VectorType) <= i; --i)
  137.         _RWSTD_THROW(bits[i],
  138.                     overflow_error,
  139.                     __rw_bitset_ConversionOverflow);
  140.  
  141.     unsigned long result = 0;
  142.  
  143.     for (size_t pos = 0; pos < N; pos++)
  144.         if (test(pos))
  145.             result |= 1UL << pos;
  146.  
  147.     return result;
  148.  
  149. //
  150. // Returns the count of the number of set bits.
  151. //
  152.  
  153. template <size_t N>
  154. size_t
  155. bitset<N>::count () const _RWSTD_THROW_SPEC_NULL
  156. {
  157.     size_t sum = 0;
  158.  
  159. #if UINT_MAX <= 4294967295
  160.     //
  161.     // A sophisticated implementaton that works if BitsPerChunk < 63
  162.     //
  163.     for (size_t i = 0; i < NELEMENTS; i++)
  164.     {
  165.         unsigned long n = bits[i];
  166.         unsigned long t = n - ((n>>1) & 033333333333) - ((n>>2) & 011111111111);
  167.         t = ((t + (t >> 3)) & 030707070707);
  168.  
  169.         unsigned long x = t & 07700770077;
  170.         unsigned long y = (t >> 6) & 07700770077;
  171.  
  172.         t = x + y;
  173.         t = ((t >> 12) + (t >> 24) + t) & 0777;
  174.         t = (t >> 6) + (t & 077);
  175.         t = t + 1;
  176.  
  177.         sum += (t >> 6) + (t & 077) - 1;
  178.     }
  179. #else
  180.     //
  181.     // The more naive implementation that always works.
  182.     //
  183.     for (size_t i = 0; i < NELEMENTS; i++)
  184.     {
  185.         unsigned long n = bits[i];
  186.         while (n)
  187.         {
  188.             n &= n-1;
  189.             sum++;
  190.         }
  191.     }
  192. #endif
  193.     return sum;
  194. }
  195.  
  196.  
  197. #ifndef _RWSTD_NO_NONTYPE_ARGS
  198. template <size_t N>
  199. istream&
  200.  operator>> (istream& is, bitset<N>& x)
  201. {
  202.     string str(N, '0');
  203.  
  204.     for (size_t count = 0; count < N && !is.eof(); )
  205.     {
  206.         char c = 0;
  207.         is >> c;
  208.         if (c == '1' || c == '0')
  209.         { 
  210.             str.append(1, c);
  211.             count++; 
  212.         }
  213.         else
  214.         {
  215.             is.putback(c);
  216.             break;
  217.         }
  218.     }
  219.  
  220.     if (str.size() == 0)
  221. #ifdef _RW_STD_IOSTREAM
  222.         is.setstate(ios::failbit);
  223. #else
  224.         is.clear(ios::failbit);
  225. #endif
  226.  
  227.     x = bitset<N>(str);
  228.  
  229.     return is;
  230. }
  231. #endif /*_RWSTD_NO_NONTYPE_ARGS*/
  232.  
  233.  
  234. #ifndef _RWSTD_NO_NAMESPACE
  235. }
  236. #endif
  237.  
  238. #pragma option pop
  239. #endif /* __BITSET_CC */
  240.